package se_dsp_report

import (
	"fmt"
	"strconv"
	"strings"
	"time"
	"wx-api/dsp-api/cache"
	"wx-api/dsp-api/config"
	"wx-api/dsp-api/errmsg"
	"wx-api/dsp-api/handlers"
	"wx-api/dsp-api/services/comm"
	"wx-api/dsp-api/utils"
)

type YmapStruct struct {
	Req   int64
	Fill  int64
	View  int64
	Click int64
	Dp    int64
	Price float64
}

func DspReportIndex(c *handlers.Controller) {
	ssp_uid := comm.GetUserInfo(c)

	tt := time.Now()

	if ssp_uid == "" {
		return
	}
	sql := "select date,sum(req) as req,sum(fill) as fill, " +
		"sum(pv) as pv, sum(ipv) as ipv, sum(click) as click, sum(iclick) as iclick, " +
		"sum(deeplink) as deeplink,sum(ideeplink) as ideeplink,sum(price) as price " +
		"from " + config.CkTableReport
	where := " where 1=1 "
	Sdate := tt.Format("2006-01-02")
	Edata := tt.AddDate(0, 0, -30).Format("2006-01-02")
	where += " and date >='" + Edata + "' and date <= '" + Sdate + "'"
	sql = sql + where + " group by date"
	ret := []DspCkReport{}
	fmt.Println(sql)
	err := config.CKDB.Select(&ret, sql)
	if err != nil {
		fmt.Println("select error:" + err.Error())
		return
	}
	yesterday := tt.AddDate(0, 0, -1).Format("2006-01-02")
	semday := tt.AddDate(0, 0, -7).Format("2006-01-02")
	ymap := map[string]YmapStruct{
		tt.AddDate(0, 0, 0).Format("2006-01-02"):  YmapStruct{},
		tt.AddDate(0, 0, -1).Format("2006-01-02"): YmapStruct{},
		tt.AddDate(0, 0, -2).Format("2006-01-02"): YmapStruct{},
		tt.AddDate(0, 0, -3).Format("2006-01-02"): YmapStruct{},
		tt.AddDate(0, 0, -4).Format("2006-01-02"): YmapStruct{},
		tt.AddDate(0, 0, -5).Format("2006-01-02"): YmapStruct{},
		tt.AddDate(0, 0, -6).Format("2006-01-02"): YmapStruct{},
	}
	sumd := float64(0)
	sums := float64(0)
	summ := float64(0)
	semdayint := utils.DecDate(semday)
	for _, val := range ret {
		ddd := val.Date[0:10]
		dddint := utils.DecDate(ddd)
		summ += val.Price     //30日
		if ddd == yesterday { //昨日
			sumd += val.Price
		}
		if semdayint <= dddint { //7日
			sums += val.Price
		}
		tmpy, ok := ymap[ddd]
		if ok {
			tmpy.Req += val.Req
			tmpy.Fill += val.Fill
			tmpy.View += val.Pv
			tmpy.Click += val.Click
			tmpy.Dp += val.Deeplink
			tmpy.Price += val.Price
			ymap[ddd] = tmpy
		}
	}
	retdata := map[string]interface{}{
		"sumobj": map[string]interface{}{
			"sumd": utils.Decimal(sumd / 100000),
			"sums": utils.Decimal(sums / 100000),
			"summ": utils.Decimal(summ / 100000),
		},
	}
	x := []string{
		tt.AddDate(0, 0, -6).Format("2006-01-02"),
		tt.AddDate(0, 0, -5).Format("2006-01-02"),
		tt.AddDate(0, 0, -4).Format("2006-01-02"),
		tt.AddDate(0, 0, -3).Format("2006-01-02"),
		tt.AddDate(0, 0, -2).Format("2006-01-02"),
		tt.AddDate(0, 0, -1).Format("2006-01-02"),
		tt.AddDate(0, 0, 0).Format("2006-01-02"),
	}
	retdata["x"] = x
	retdata["y"] = DspReportIndexY(x, ymap)
	c.SetErrorMsg(retdata, errmsg.SuccessMsg())
	return
}

func DspReportIndexY(x []string, y map[string]YmapStruct) []interface{} {
	y_req := make([]int64, len(x))
	y_fill := make([]int64, len(x))
	y_view := make([]int64, len(x))
	y_click := make([]int64, len(x))
	y_dp := make([]int64, len(x))
	y_price := make([]float64, len(x))
	for k, s := range x {
		tmp, ok := y[s]
		if ok {
			y_req[k] = tmp.Req
			y_fill[k] = tmp.Fill
			y_view[k] = tmp.View
			y_click[k] = tmp.Click
			y_dp[k] = tmp.Dp
			y_price[k] = utils.Decimal(tmp.Price / 100000)
		}
	}
	return []interface{}{
		y_req, y_fill, y_view, y_click, y_dp, y_price,
	}
}

type ParamReport struct {
	Sdate    string   `form:"stime" json:"stime"`
	Edata    string   `form:"etime" json:"etime"`
	Grp      string   `form:"grp" json:"grp"`
	MediaIds []string `form:"media_ids" json:"media_ids"`
	AppIds   []string `form:"app_ids" json:"app_ids"`
	SlotIds  []string `form:"slot_ids" json:"slot_ids"`
	AdvIds   []string `form:"adv_ids" json:"adv_ids"`
	PlanIds  []string `form:"plan_ids" json:"plan_ids"`
	Cids     []string `form:"cids" json:"cids"`
	Page     int64    `form:"page" json:"page"`
	PageSize int64    `form:"page_size" json:"page_size"`
}

func DspReport(c *handlers.Controller) {
	var form ParamReport
	if err := c.Ctx.ShouldBind(&form); err != nil {
		fmt.Println(err)
		c.BadRequest()
		return
	}
	ssp_uid := comm.GetUserInfo(c)
	if ssp_uid == "" {
		return
	}
	if form.Page == 0 {
		form.Page = 1
	}
	if form.PageSize == 0 {
		form.PageSize = 50
	}
	if form.Sdate == "" {
		form.Sdate = time.Now().Format("2006-01-02")
	}
	if form.Edata == "" {
		form.Edata = time.Now().Format("2006-01-02")
	}
	sql := "select date,media_id,app_id,slot_id,adv_id,plan_id,cid,sum(req) as req,sum(fill) as fill, " +
		"sum(pv) as pv, sum(ipv) as ipv, sum(click) as click, sum(iclick) as iclick, " +
		"sum(deeplink) as deeplink,sum(ideeplink) as ideeplink,sum(price) as price " +
		"from " + config.CkTableReport
	where := " where adv_id != '' "
	if form.Sdate == form.Edata {
		where += " and date ='" + form.Sdate + "'"
	}
	if form.Sdate != form.Edata {
		where += " and date <='" + form.Edata + "' and date >= '" + form.Sdate + "'"
	}
	if len(form.MediaIds) > 0 {
		where += " and media_id in ('" + strings.Join(form.MediaIds, "','") + "')"
	}
	if len(form.AppIds) > 0 {
		where += " and app_id in ('" + strings.Join(form.AppIds, "','") + "')"
	}
	if len(form.SlotIds) > 0 {
		where += " and slot_id in ('" + strings.Join(form.SlotIds, "','") + "')"
	}
	if len(form.AdvIds) > 0 {
		where += " and adv_id in ('" + strings.Join(form.AdvIds, "','") + "')"
	}
	if len(form.PlanIds) > 0 {
		where += " and plan_id in ('" + strings.Join(form.PlanIds, "','") + "')"
	}
	if len(form.Cids) > 0 {
		where += " and cid in ('" + strings.Join(form.Cids, "','") + "')"
	}
	order := " order by date desc"
	group := " group by media_id,app_id,slot_id,adv_id,plan_id,cid"
	if form.Grp == "1" {
		group += ",date,date_hour"
		order = " order by date,date_hour desc"
	} else {
		group += ",date"
	}
	limitto := (form.Page - 1) * form.PageSize
	limitfo := form.PageSize
	limit := " limit " + strconv.Itoa(int(limitto)) + "," + strconv.Itoa(int(limitfo))
	//获取总页数
	count := config.GetCkCount(config.CkTableReport + where + group)
	retd := config.DataList{
		PageSize: form.PageSize,
		PageNum:  form.Page,
		Total:    count,
	}

	sql = sql + where + group + order + limit
	fmt.Println("================")
	fmt.Println(sql)
	ret := []DspCkReport{}
	err := config.CKDB.Select(&ret, sql)
	if err != nil {
		fmt.Println("select error:" + err.Error())
		return
	}
	for i, tmp_val := range ret {
		val := tmp_val
		if val.Fill == 0 && val.Pv == 0 && val.Ipv == 0 {
			continue
		}
		m_info, ok := cache.CacheDspMediaMapNGet(val.MediaId)
		if ok {
			val.MediaName = m_info.Name
		} else {
			val.MediaName = "-"
		}
		appinfo, ok := cache.CacheDspMediaAppMapNGet(val.AppId)
		if ok {
			val.AppName = appinfo.Name
		} else {
			val.AppName = "-"
		}
		slotinfo, ok := cache.CacheDspMediaSlotMapNGet(val.SlotId)
		if ok {
			val.SlotName = slotinfo.Name
		} else {
			val.SlotName = "-"
		}
		advinfo, ok := cache.CacheDspAdvertiserMapNGet(val.AdvId)
		if ok {
			val.AdvName = advinfo.Name
		} else {
			val.AdvName = "-"
		}
		planinfo, ok := cache.CacheDspAdvPlanMapNGet(val.PlanId)
		if ok {
			val.PlanName = planinfo.Name
		} else {
			val.PlanName = "-"
		}
		cinfo, ok := cache.CacheDspAdvCreativeMapNGet(val.Cid)
		if ok {
			val.CName = cinfo.Name
		} else {
			val.CName = "-"
		}
		val.Date = val.Date[0:10]
		val.Price = utils.Decimal(val.Price / 100000)
		if val.Req > 0 {
			val.FillRate = utils.Decimal(float64(val.Fill) / float64(val.Req) * 100)
			val.Rpm = utils.Decimal((val.Price / float64(val.Req)) * 10000)
		}
		if val.Fill > 0 {
			val.PvRate = utils.Decimal(float64(val.Pv) / float64(val.Fill) * 100)
		}
		if val.Pv > 0 {
			val.ClickRate = utils.Decimal(float64(val.Click) / float64(val.Pv) * 100)
			val.Cpm = utils.Decimal(val.Price / float64(val.Pv) * 1000)
		}
		if val.Click > 0 {
			val.DeeplinkRate = utils.Decimal(float64(val.Deeplink) / float64(val.Click) * 100)
			val.Cpc = utils.Decimal(val.Price / float64(val.Click))
		}
		ret[i] = val
	}
	retd.List = ret
	c.SetErrorMsg(retd, errmsg.SuccessMsg())
	return
}

type DspCkReport struct {
	Date         string  `db:"date" json:"date" bson:"date"`
	DateHour     string  `db:"date_hour" json:"date_hour" bson:"date_hour"`
	MediaId      string  `db:"media_id" json:"media_id" bson:"media_id"`
	MediaName    string  `db:"_" json:"media_name" bson:"media_name"`
	AppId        string  `db:"app_id" json:"app_id" bson:"app_id"`
	AppName      string  `db:"_" json:"app_name" bson:"app_name"`
	SlotId       string  `db:"slot_id" json:"slot_id" bson:"slot_id"`
	SlotName     string  `db:"_" json:"slot_name" bson:"slot_name"`
	AdvId        string  `db:"adv_id" json:"adv_id" bson:"adv_id"`
	AdvName      string  `db:"_" json:"adv_name" bson:"adv_name"`
	PlanId       string  `db:"plan_id" json:"plan_id" bson:"plan_id"`
	PlanName     string  `db:"_" json:"plan_name" bson:"plan_name"`
	Cid          string  `db:"cid" json:"cid" bson:"cid"`
	CName        string  `db:"_" json:"cname" bson:"cname"`
	Req          int64   `db:"req" json:"req" bson:"req"`
	Fill         int64   `db:"fill" json:"fill" bson:"fill"`
	Pv           int64   `db:"pv" json:"pv" bson:"pv"`
	Ipv          int64   `db:"ipv" json:"ipv" bson:"ipv"`
	Click        int64   `db:"click" json:"click" bson:"click"`
	Iclick       int64   `db:"iclick" json:"iclick" bson:"iclick"`
	Deeplink     int64   `db:"deeplink" json:"deeplink" bson:"deeplink"`
	Ideeplink    int64   `db:"ideeplink" json:"ideeplink" bson:"ideeplink"`
	Price        float64 `db:"price" json:"price" bson:"price"`
	FillRate     float64 `db:"_" json:"fill_rate" bson:"fill_rate"`
	PvRate       float64 `db:"_" json:"pv_rate" bson:"pv_rate"`
	ClickRate    float64 `db:"_" json:"click_rate" bson:"click_rate"`
	DeeplinkRate float64 `db:"_" json:"deeplink_rate" bson:"deeplink_rate"`
	Rpm          float64 `db:"_" json:"rpm" bson:"rpm"`
	Cpm          float64 `db:"_" json:"cpm" bson:"cpm"`
	Cpc          float64 `db:"_" json:"cpc" bson:"cpc"`
}
